package it.ap.sa.acqua.auth.policy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import it.ap.sa.core.configuration.policy.RuntimePolicyInfo;

/**
 * @author marianna
 */
public class GlobalTrackerUserPolicy {
	
	/** 
	 * Mappa contenente le relazioni User/Policy 
	 */
	private static Map<Long, List<RuntimePolicyInfo>> map = new HashMap<Long, List<RuntimePolicyInfo>>();

	/**
	 * Ritorna l'instanza della mappa corrente, se non è inizilizzata prima di ritornarla ricerca sul db le policy attive.
	 * 
	 * @return {@link Map<Long, List<RuntimePolicyInfo>>}
	 */
	public static Map<Long, List<RuntimePolicyInfo>> getInstance() {
		return map;
	}
	
	/**
	 * Aggiunge la nuova policy alla mappa
	 * 
	 * @param {@link RuntimePolicyInfo} policy
	 */
	public static void put(RuntimePolicyInfo policy) {
		List<RuntimePolicyInfo> list = null;
		
		/** **/
		if( getInstance().containsKey(policy.getUserId()) )
			list = getInstance().get(policy.getUserId());
		else
			list = new ArrayList<RuntimePolicyInfo>();
		
		list.add(policy);
		
		// rinserisco la lista di policy aggiornata per l'utente
		getInstance().put(policy.getUserId(), list);
	}
	
	/**
	 * Rimuove la policy dalla mappa.
	 * 
	 * @param {@link RuntimePolicyInfo} policy
	 */
	private static void remove(RuntimePolicyInfo policy) {
		/** **/
		if( getInstance().containsKey(policy.getUserId()) ){
			List<RuntimePolicyInfo> list = getInstance().get(policy.getUserId());
			
			for (int i = 0; i < list.size(); i++) {
				if(list.get(i).getPolicyId().longValue() == policy.getPolicyId().longValue()) {
					list.remove(i);
					break;
				}
			}
			
			getInstance().put(policy.getUserId(), list);
		}
	}
	
	/**
	 * Determina l'operazione da eseguire.
	 * 
	 * @param {@link RuntimePolicyInfo} policy
	 */
	public static void process(RuntimePolicyInfo policy) {
		if(policy.getState().equals(PolicyAnalysisState.OPEN.name()) )
			put(policy);
		else
			if(policy.getState().equals(PolicyAnalysisState.REMOVED.name()) )
				remove(policy);
		else
			if(policy.getState().equals(PolicyAnalysisState.CLOSE.name()) )
				remove(policy);	
	}
}
